package com.weblog.weblog.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weblog.weblog.admin.model.vo.dashboard.FindDashboardPVStatisticsInfoRspVO;
import com.weblog.weblog.admin.model.vo.dashboard.FindDashboardStatisticsInfoRspVO;
import com.weblog.weblog.admin.service.AdminDashboardService;
import com.weblog.weblog.common.constant.Constant;
import com.weblog.weblog.common.domain.dos.ArticleDO;
import com.weblog.weblog.common.domain.dos.ArticlePublishCountDO;
import com.weblog.weblog.common.domain.dos.StatisticsArticlePVDO;
import com.weblog.weblog.common.domain.mapper.ArticleMapper;
import com.weblog.weblog.common.domain.mapper.CategoryMapper;
import com.weblog.weblog.common.domain.mapper.StatisticsArticlePVMapper;
import com.weblog.weblog.common.domain.mapper.TagMapper;
import com.weblog.weblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author gc
 * @date 2023年11月11日 20:10
 */
@Service
@Slf4j
public class AdminDashboardServiceImpl implements AdminDashboardService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private StatisticsArticlePVMapper articlePVMapper;

    /**
     * 获取仪表盘基础信息
     */
    @Override
    public Response findDashboardStatistics() {

        Long articleTotalCount = articleMapper.selectCount(Wrappers.emptyWrapper());

        Long categoryTotalCount = categoryMapper.selectCount(Wrappers.emptyWrapper());

        Long tagTotalCount = tagMapper.selectCount(Wrappers.emptyWrapper());

        List<ArticleDO> articleDOS = articleMapper.selectAllReadNum();
        Long pvTotalCount = 0L;

        if(!CollectionUtils.isEmpty(articleDOS)){
            pvTotalCount = articleDOS.stream().mapToLong(ArticleDO::getReadNum).sum();
        }

        FindDashboardStatisticsInfoRspVO vo = FindDashboardStatisticsInfoRspVO.builder()
                .articleTotalCount(articleTotalCount)
                .categoryTotalCount(categoryTotalCount)
                .tagTotalCount(tagTotalCount)
                .pvTotalCount(pvTotalCount)
                .build();

        return Response.success(vo);

    }

    /**
     * 获取文章发布热点统计信息
     */
    @Override
    public Response findDashboardPublishArticleStatistics() {
        LocalDate currDate = LocalDate.now();

        LocalDate startDate = currDate.minusYears(1);

        List<ArticlePublishCountDO> articlePublishCountDOS = articleMapper.selectDateArticlePublishCount(startDate,currDate);

        Map<LocalDate,Long> map = null;
        if(!CollectionUtils.isEmpty(articlePublishCountDOS)){
            Map<LocalDate,Long> dateArticleCountMap = articlePublishCountDOS.stream()
                    .collect(Collectors.toMap(ArticlePublishCountDO::getDate , ArticlePublishCountDO::getCount));

            map = Maps.newLinkedHashMap();

            for (;startDate.isBefore(currDate) || startDate.isEqual(currDate); startDate = startDate.plusDays(1)){
                Long count = dateArticleCountMap.get(startDate);

                map.put(startDate, Objects.isNull(count) ? 0 : count);
            }
        }
        return Response.success(map);
    }

    @Override
    public Response findDashboardPVStatistics() {
        List<StatisticsArticlePVDO> articlePVDOS = articlePVMapper.selectLatestWeekRecords();

        FindDashboardPVStatisticsInfoRspVO vo = null;
        if (!CollectionUtils.isEmpty(articlePVDOS)){
            // 转 Map, 方便后续通过日期获取 PV 访问量
            Map<LocalDate, Long> pvDateCountMap = articlePVDOS.stream()
                    .collect(Collectors.toMap(StatisticsArticlePVDO::getPvDate, StatisticsArticlePVDO::getPvCount));

            // 日期集合
            List<String> pvDates = Lists.newArrayList();
            // PV 集合
            List<Long> pvCounts = Lists.newArrayList();

            // 当前日期
            LocalDate currDate = LocalDate.now();
            // 一周前
            LocalDate tmpDate = currDate.minusWeeks(1);
            // 从一周前开始循环
            for (; tmpDate.isBefore(currDate) || tmpDate.isEqual(currDate); tmpDate = tmpDate.plusDays(1)) {
                // 设置对应日期的 PV 访问量
                pvDates.add(tmpDate.format(Constant.MONTH_DAY_FORMATTER));
                Long pvCount = pvDateCountMap.get(tmpDate);
                pvCounts.add(Objects.isNull(pvCount) ? 0 : pvCount);
            }

            vo = FindDashboardPVStatisticsInfoRspVO.builder()
                    .pvDates(pvDates)
                    .pvCounts(pvCounts)
                    .build();
        }

        return Response.success(vo);
    }
}
